package com.xiaobai.java_core.reflect;

import org.springframework.util.ObjectUtils;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wangtw
 * @ClassName ObectAnalyzer
 * @description: 对象分析
 * @date 2023/1/1714:10
 */
public class ObjectAnalyzer {

    private ArrayList<Object> visited = new ArrayList<>();

    public String toString(Object obj) throws ReflectiveOperationException {
        if (obj == null) {
            return "null";
        }
        if (visited.contains(obj)) {
            return "...";
        }
        visited.add(obj);

        Class<?> objClass = obj.getClass();
        if (objClass == String.class) {
            return (String) obj;
        }
        // 检查对象是否为数组类
        if (objClass.isArray()) {
            // getComponentType返回数组元素的class对象
            String elementType = objClass.getComponentType() + "[]{";
            for (int i = 0; i < Array.getLength(obj); i++) {
                if (i > 0) {
                    elementType += ", ";
                }
                Object val = Array.get(obj, i);

                // 判断数组元素是否是基本类型
                if (objClass.getComponentType().isPrimitive()) {
                    elementType += val;
                } else {
                    elementType += toString(val);
                }
            }
            return elementType + "}";
        }
        String objClassName  = "";
        do {
            Field[] declaredFields = objClass.getDeclaredFields();
            AccessibleObject.setAccessible(declaredFields, true);

            // 筛选非static属性
            List<Field> fieldList = Arrays.stream(declaredFields)
                    .filter(declaredField -> !Modifier.isStatic(declaredField.getModifiers()))
                    .collect(Collectors.toList());
            if (ObjectUtils.isEmpty(fieldList)) {
                objClass = objClass.getSuperclass();
                continue;
            }
            objClassName += objClass.getName() + "[";
            for (Field declaredField : fieldList) {
                if (!objClassName.endsWith("[")) {
                    objClassName += ",";
                }
                objClassName += declaredField.getName() + "=";
                Object val = declaredField.get(obj);
                Class<?> declaredFieldType = declaredField.getType();
                // 判断当前类型是否是基本类型
                if (declaredFieldType.isPrimitive()) {
                    objClassName += val;
                } else {
                    objClassName += toString(val);
                }
            }

            objClassName += "]";
            objClass = objClass.getSuperclass();
        } while (objClass != null);

        return objClassName;
    }
}
